﻿#pragma once
#include <string>
#include <queue>
#include <thread>
#include <mutex>
#include <atomic>
#include <memory>
#include <functional>
#include <condition_variable>

#include "connect.hpp"

//单例模式
class Connect_pool
{
public:
    static Connect_pool *get_instance();

    //给外部提供的接口，返回可用的空闲连接
    std::shared_ptr<Connect> get_connect();

    //初始化配置
    static bool set_configure(
        std::string ip,
        unsigned short port,
        std::string user,
        std::string password,
        std::string dbname,
        int init_size = 50,          //连接池初始连接量
        int max_size = 2048,           //连接的最大连接量
        int max_freeTime = 60,        //连接池的最大空闲时间(s)
        int connection_timeout = 100 //连接池获取连接的超时时间(ms)
    );
private:
    Connect_pool();

    // 运行在独立的线程，专门负责生产新的连接
    void produce_connection();

    //释放空闲连接
    void scan_connection();

private:
    static std::string ip_;
    static unsigned short port_;
    static std::string user_;
    static std::string password_;
    static std::string dbname_;

    static int init_size_;          //连接池初始连接量
    static int max_size_;           //连接的最大连接量
    static int max_freeTime_;        //连接池的最大空闲时间(s)
    static int connection_timeout_; //连接池获取连接的超时时间(ms)

    static bool is_init_;

    std::queue<Connect *> connect_queue_; //储存mysql连接的队列
    std::mutex queue_mutex_;              //维护线程安全
    std::atomic_int connect_cnt_;         //记录连接所创建的connect连接的总数量

    std::condition_variable condition_; //设置条件变量，负责生产线程的唤醒和休眠
};